home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: DZDrone.c
- *
- * Contents: A drone object represents the position of an player or drone.
- *
- * Copyright © 1996 Apple Computer, Inc.
- */
-
- #include <assert.h>
- #include <math.h>
- #include <stdlib.h>
-
- #include <Components.h>
- #include <Dialogs.h>
- #include <Events.h>
- #include <QuickDraw.h>
- #include <Resources.h>
- #include <Sound.h>
- #include <SoundComponents.h>
- #include <SoundInput.h>
- #include <ToolUtils.h>
- #include <Types.h>
-
- #include <QD3D.h>
- #include <QD3DCamera.h>
- #include <QD3DDrawContext.h>
- #include <QD3DGeometry.h>
- #include <QD3DMath.h>
- #include <QD3DPick.h>
- #include <QD3DSet.h>
- #include <QD3DShader.h>
- #include <QD3DStyle.h>
- #include <QD3DTransform.h>
- #include <QD3DView.h>
-
- #include "SoundSprocket.h"
-
- #include "DZDisplay.h"
- #include "DZDrone.h"
- #include "DZGame.h"
- #include "DZResource.h"
- #include "DZSound.h"
- #include "DZThumbprint.h"
- #include "DZUtils.h"
-
- #ifndef SELF_DRONE_HAS_FRICTION
- #define SELF_DRONE_HAS_FRICTION 1
- #endif
-
-
- #define IS_SELF_DRONE(inDrone) (inDrone->thumbprint == kThumbprint_SelfDrone)
- #define IS_AUTO_DRONE(inDrone) (inDrone->thumbprint == kThumbprint_AutoDrone)
- #define IS_BULLET_DRONE(inDrone) (inDrone->thumbprint == kThumbprint_BulletDrone)
- #define IS_DRONE(inDrone) (IS_SELF_DRONE(inDrone) || IS_AUTO_DRONE(inDrone) || IS_BULLET_DRONE(inDrone))
-
- #define SELF_DRONE_INITIAL_SPEED 0.50 // In units per second
- #define SELF_DRONE_MAX_ACCEL 10.0 // In units per second per second
- #define SELF_DRONE_FRICTION 0.80 // as a percentage (1.00 would be no friction)
-
- #define AUTO_DRONE_LEAD 5.0 // Drone target leads by this distance (in units)
- #define AUTO_DRONE_ACCEL 2.0 // Drone acceleration (units per second per second)
- #define AUTO_DRONE_TURN_RATE 1.8 // In radians per second
- #define AUTO_DRONE_BURN_TIME 3.0 // In seconds
- #define AUTO_DRONE_REST_TIME 1.0 // In seconds
- #define AUTO_DRONE_EXPLOSION_TIME 3.0 // In seconds
- #define AUTO_DRONE_FADE_TIME 0.25 // Fraction of AUTO_DRONE_EXPLOSION_TIME for fade
- #define AUTO_DRONE_MIN_SCALE 0.2 // Initial scale for explosion
-
- #define AUTO_DRONE_IDLE_REF_DIST 2.0
- #define AUTO_DRONE_BURN_REF_DIST 5.0
- #define AUTO_DRONE_EXPL_REF_DIST 30.0
-
- #define BULLET_DRONE_OFFSET 0.2 // Offset from self to bullet initial position
- #define BULLET_DRONE_SPEED 50.0 // In units per second
- #define BULLET_DRONE_LIMIT 50.0 // Maximum length of a bullet
-
- #define HUD_SCALE 0.02 // Scale of HUD
- #define HUD_HEIGHT 0.5 // cos(angle) at which to consider out-of-plane
-
-
- enum {
- kDroneDrawContextSize = 5 // Used for picking
- };
-
-
- typedef enum TDroneOrder { // In order of evaluation
- kDroneOrder_Self,
- kDroneOrder_Auto,
- kDroneOrder_Bullet
- } TDroneOrder;
-
-
- typedef void (*TDroneMoveMethod)(
- TDroneObject inDrone);
-
- typedef void (*TDroneUpdateSoundMethod)(
- TDroneObject inDrone);
-
- typedef void (*TDroneSubmitMethod)(
- TDroneObject inDrone,
- Boolean inHUDVisible,
- TQ3ViewObject inView);
-
- typedef void (*TDronePickSubmitMethod)(
- TDroneObject inDrone,
- TQ3ViewObject inView);
-
- typedef void (*TDroneHitMethod)(
- TDroneObject inDrone);
-
-
- typedef enum TAutoSound {
- kAutoSound_None,
- kAutoSound_Idle,
- kAutoSound_Burn,
- kAutoSound_Explosion
- } TAutoSound;
-
- typedef enum TAutoMode {
- kAutoMode_Idle,
- kAutoMode_Burn,
- kAutoMode_Rest,
- kAutoMode_Explosion
- } TAutoMode;
-
-
- typedef struct TDroneData {
- TThumbprint thumbprint; // For validation
-
- TDroneMoveMethod moveMethod; // Method: Drone_Move
- TDroneUpdateSoundMethod updateSoundMethod; // Method: Drone_UpdateSound
- TDroneSubmitMethod submitMethod; // Method: Drone_Submit
- TDronePickSubmitMethod pickSubmitMethod; // Method: Drone_PickSubmit
- TDroneHitMethod hitMethod; // Method: Drone_Hit
-
- TDroneObject prev; // The global list of drones
- TDroneObject next;
- TDroneOrder order; // Sort key
-
- Boolean mark; // Is this drone marked to die?
-
- TQ3Point3D position; // Current position
- TQ3Point3D position1; // Previous position
-
- TQ3Vector3D velocity; // Change in position over time
- TQ3Vector3D velocity1; // Previous velocity
-
- TQ3Vector3D acceleration; // Change in velocity over time
-
- TQ3Vector3D direction; // Forward (model X axis)
- TQ3Vector3D up; // Vertical (model Y axis)
- TQ3Vector3D cross; // Horizontal (model Z axis)
-
- TQ3Object geometry; // The shape of the drone
-
- SndChannelPtr autoSndChannel; // Auto: Sound channel
- SSpSourceReference autoSource; // Auto: 3D sound source
- TAutoSound autoSound; // Auto: Sound currently playing
- TDroneObject autoInterest; // Auto: Drone that we're looking at
- TQ3Vector3D autoVelocity; // Auto: Drone velocity (instantaneous)
- TAutoMode autoMode; // Auto: Current state
- unsigned long autoModeTimeout; // Auto: When does mode expire?
- float autoDistance; // Auto: Last distance from target
- float autoExplosion; // Auto: 0=start; 1=end of explosion
-
- TQ3Point3D bulletOrigin; // Bullet: Starting position of the bullet
- } TDroneData;
-
-
- static TDroneObject gDroneList = NULL;
- static TQ3Object gDroneAutoGeometry = NULL;
- static TQ3Object gDroneAutoBurnGeometry = NULL;
- static TQ3Object gDroneAutoExplosionGeometry = NULL;
- static TQ3AttributeSet gDroneBulletColor = NULL;
- static TQ3ShaderObject gDroneNULLIllumination = NULL;
- static TQ3ViewObject gDroneView = NULL;
- static TQ3DrawContextObject gDroneDrawContext = NULL;
- static TQ3CameraObject gDroneCamera = NULL;
- static TQ3PickObject gDronePick = NULL;
-
- static SndListHandle gDroneAutoSndIdle = NULL;
- static SndListHandle gDroneAutoSndBurn = NULL;
- static SndListHandle gDroneAutoSndExplosion = NULL;
-
- static long gDroneAutoSndIdleOffset = 0;
- static long gDroneAutoSndBurnOffset = 0;
- static long gDroneAutoSndExplosionOffset = 0;
-
- static TQ3GeometryObject gDroneAutoMarkerEqual = NULL;
- static TQ3GeometryObject gDroneAutoMarkerAbove = NULL;
- static TQ3GeometryObject gDroneAutoMarkerBelow = NULL;
-
- static unsigned char gDroneAutoMarkerDataEqual[8] =
- {0x38, 0x44, 0x82, 0x92, 0x82, 0x44, 0x38, 0x00};
-
- static unsigned char gDroneAutoMarkerDataAbove[8] =
- {0x38, 0x54, 0x92, 0xFE, 0x92, 0x54, 0x38, 0x00};
-
- static unsigned char gDroneAutoMarkerDataBelow[8] =
- {0x38, 0x44, 0x82, 0xFE, 0x82, 0x44, 0x38, 0x00};
-
- static Boolean gDroneAutoCheckFilterVersion = true;
-
-
- static TDroneObject Drone_New(
- TDroneOrder inOrder);
-
- static void SelfDrone_Move(
- TDroneObject inDrone);
-
- static void AutoDrone_Move(
- TDroneObject inDrone);
-
- static void BulletDrone_Move(
- TDroneObject inDrone);
-
- static void AutoDrone_UpdateSound(
- TDroneObject inDrone);
-
- static void AutoDrone_Submit(
- TDroneObject inDrone,
- Boolean inHUDVisible,
- TQ3ViewObject inView);
-
- static void BulletDrone_Submit(
- TDroneObject inDrone,
- Boolean inHUDVisible,
- TQ3ViewObject inView);
-
- static void Drone_PickSubmit(
- TDroneObject inDrone,
- TQ3ViewObject inView);
-
- static void AutoDrone_PickSubmit(
- TDroneObject inDrone,
- TQ3ViewObject inView);
-
- static void Drone_Hit(
- TDroneObject inDrone);
-
- static void AutoDrone_Hit(
- TDroneObject inDrone);
-
- void Drone_GetMatrix(
- TDroneObject inDrone,
- TQ3Matrix4x4* outMatrix);
-
-
- /* =============================================================================
- * Drone_Init (external)
- *
- * Initializes the drone stuff.
- * ========================================================================== */
- void Drone_Init(
- void)
- {
- TQ3ColorRGB color;
- TQ3PixmapDrawContextData pixmapDrawContextData;
- TQ3ViewAngleAspectCameraData viewAngleCameraData;
- TQ3WindowPointPickData windowPointPickData;
- TQ3MarkerData markerData;
-
- // Set up the autopilot drone geometry
- gDroneAutoGeometry = Get3DMFResource(k3DMFID_AutoDrone);
- assert(gDroneAutoGeometry != NULL);
-
- // Set up the autopilot drone burn geometry
- gDroneAutoBurnGeometry = Get3DMFResource(k3DMFID_AutoDroneBurn);
- assert(gDroneAutoBurnGeometry != NULL);
-
- // Set up the autopilot drone explosion geometry
- gDroneAutoExplosionGeometry = Get3DMFResource(k3DMFID_AutoDroneExplosion);
- assert(gDroneAutoExplosionGeometry != NULL);
-
- // Read in the autopilot drone sounds
- gDroneAutoSndIdle = (SndListHandle) GetResource('snd ', kSndID_AutoIdle);
- assert(gDroneAutoSndIdle != NULL);
-
- gDroneAutoSndBurn = (SndListHandle) GetResource('snd ', kSndID_AutoBurn);
- assert(gDroneAutoSndBurn != NULL);
-
- gDroneAutoSndExplosion = (SndListHandle) GetResource('snd ', kSndID_AutoExplosion);
- assert(gDroneAutoSndExplosion != NULL);
-
- GetSoundHeaderOffset(gDroneAutoSndIdle, &gDroneAutoSndIdleOffset);
- GetSoundHeaderOffset(gDroneAutoSndBurn, &gDroneAutoSndBurnOffset);
- GetSoundHeaderOffset(gDroneAutoSndExplosion, &gDroneAutoSndExplosionOffset);
-
- // Set up the bullet drone line color
- gDroneBulletColor = Q3AttributeSet_New();
- assert(gDroneBulletColor != NULL);
-
- color.r = 1.0;
- color.g = 0.8;
- color.b = 0.1;
-
- Q3AttributeSet_Add(gDroneBulletColor, kQ3AttributeTypeDiffuseColor, &color);
-
- // Create the bullet null illum shader
- gDroneNULLIllumination = Q3NULLIllumination_New();
- assert(gDroneNULLIllumination != NULL);
-
- // Create the view that we use for bullet collision detection
- gDroneView = Q3View_New();
- assert(gDroneView != NULL);
-
- // Create its draw context
- pixmapDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor;
- pixmapDrawContextData.drawContextData.clearImageColor.a = 1.0;
- pixmapDrawContextData.drawContextData.clearImageColor.r = 0.0;
- pixmapDrawContextData.drawContextData.clearImageColor.g = 0.0;
- pixmapDrawContextData.drawContextData.clearImageColor.b = 0.0;
- pixmapDrawContextData.drawContextData.paneState = kQ3False;
- pixmapDrawContextData.drawContextData.maskState = kQ3False;
- pixmapDrawContextData.drawContextData.doubleBufferState = kQ3False;
- pixmapDrawContextData.pixmap.width = kDroneDrawContextSize;
- pixmapDrawContextData.pixmap.height = kDroneDrawContextSize;
- pixmapDrawContextData.pixmap.rowBytes = pixmapDrawContextData.pixmap.width*4;
- pixmapDrawContextData.pixmap.pixelSize = 32;
- pixmapDrawContextData.pixmap.pixelType = kQ3PixelTypeRGB32;
- pixmapDrawContextData.pixmap.bitOrder = kQ3EndianBig;
- pixmapDrawContextData.pixmap.byteOrder = kQ3EndianBig;
- pixmapDrawContextData.pixmap.image = malloc(pixmapDrawContextData.pixmap.height*pixmapDrawContextData.pixmap.rowBytes);
-
- gDroneDrawContext = Q3PixmapDrawContext_New(&pixmapDrawContextData);
- assert(gDroneDrawContext != NULL);
-
- Q3View_SetDrawContext(gDroneView, gDroneDrawContext);
-
- // Create its camera
- viewAngleCameraData.cameraData.placement.cameraLocation.x = 0.0;
- viewAngleCameraData.cameraData.placement.cameraLocation.y = 0.0;
- viewAngleCameraData.cameraData.placement.cameraLocation.z = 0.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.x = 1.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.y = 0.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.z = 0.0;
- viewAngleCameraData.cameraData.placement.upVector.x = 0.0;
- viewAngleCameraData.cameraData.placement.upVector.y = 1.0;
- viewAngleCameraData.cameraData.placement.upVector.z = 0.0;
- viewAngleCameraData.cameraData.range.hither = 0.1;
- viewAngleCameraData.cameraData.range.yon = BULLET_DRONE_LIMIT;
- viewAngleCameraData.cameraData.viewPort.origin.x = -1.0;
- viewAngleCameraData.cameraData.viewPort.origin.y = 1.0;
- viewAngleCameraData.cameraData.viewPort.width = 2.0;
- viewAngleCameraData.cameraData.viewPort.height = 2.0;
- viewAngleCameraData.fov = 0.1;
- viewAngleCameraData.aspectRatioXToY = pixmapDrawContextData.pixmap.width/pixmapDrawContextData.pixmap.height;
-
- gDroneCamera = Q3ViewAngleAspectCamera_New(&viewAngleCameraData);
- assert(gDroneCamera != NULL);
-
- Q3View_SetCamera(gDroneView, gDroneCamera);
-
- // Create the pick object
- windowPointPickData.data.sort = kQ3PickSortNearToFar;
- windowPointPickData.data.mask = kQ3PickDetailMaskPickID | kQ3PickDetailMaskDistance;
- windowPointPickData.data.numHitsToReturn = kQ3ReturnAllHits;
- windowPointPickData.point.x = 0.5*pixmapDrawContextData.pixmap.width;
- windowPointPickData.point.y = 0.5*pixmapDrawContextData.pixmap.height;
- windowPointPickData.vertexTolerance = 0.0;
- windowPointPickData.edgeTolerance = 0.0;
-
- gDronePick = Q3WindowPointPick_New(&windowPointPickData);
- assert(gDronePick != NULL);
-
- // Create the autodrone markers
- markerData.location.x = 0.0;
- markerData.location.y = 0.0;
- markerData.location.z = 0.0;
- markerData.xOffset = -3;
- markerData.yOffset = -3;
- markerData.bitmap.width = 8;
- markerData.bitmap.height = 8;
- markerData.bitmap.rowBytes = 1;
- markerData.bitmap.bitOrder = kQ3EndianBig;
- markerData.markerAttributeSet = Q3AttributeSet_New();
-
- assert(markerData.markerAttributeSet != NULL);
-
- color.r = 1.0;
- color.g = 1.0;
- color.b = 0.4;
-
- Q3AttributeSet_Add(markerData.markerAttributeSet, kQ3AttributeTypeDiffuseColor, &color);
-
- markerData.bitmap.image = (unsigned char*) gDroneAutoMarkerDataEqual;
- gDroneAutoMarkerEqual = Q3Marker_New(&markerData);
- assert(gDroneAutoMarkerEqual != NULL);
-
- markerData.bitmap.image = (unsigned char*) gDroneAutoMarkerDataAbove;
- gDroneAutoMarkerAbove = Q3Marker_New(&markerData);
- assert(gDroneAutoMarkerAbove != NULL);
-
- markerData.bitmap.image = (unsigned char*) gDroneAutoMarkerDataBelow;
- gDroneAutoMarkerBelow = Q3Marker_New(&markerData);
- assert(gDroneAutoMarkerBelow != NULL);
-
- Q3Object_Dispose(markerData.markerAttributeSet);
- markerData.markerAttributeSet = NULL;
- }
-
-
- /* =============================================================================
- * Drone_Exit (external)
- *
- * Prepares for exit.
- * ========================================================================== */
- void Drone_Exit(
- void)
- {
- while (gDroneList != NULL)
- {
- Drone_Dispose(gDroneList);
- }
-
- if (gDroneAutoGeometry != NULL)
- {
- Q3Object_Dispose(gDroneAutoGeometry);
- gDroneAutoGeometry = NULL;
- }
-
- if (gDroneAutoBurnGeometry != NULL)
- {
- Q3Object_Dispose(gDroneAutoBurnGeometry);
- gDroneAutoBurnGeometry = NULL;
- }
-
- if (gDroneAutoExplosionGeometry != NULL)
- {
- Q3Object_Dispose(gDroneAutoExplosionGeometry);
- gDroneAutoExplosionGeometry = NULL;
- }
-
- if (gDroneAutoSndIdle != NULL)
- {
- ReleaseResource((Handle) gDroneAutoSndIdle);
- gDroneAutoSndIdle = NULL;
- }
-
- if (gDroneAutoSndBurn != NULL)
- {
- ReleaseResource((Handle) gDroneAutoSndBurn);
- gDroneAutoSndBurn = NULL;
- }
-
- if (gDroneAutoSndExplosion != NULL)
- {
- ReleaseResource((Handle) gDroneAutoSndExplosion);
- gDroneAutoSndExplosion = NULL;
- }
-
- if (gDroneBulletColor != NULL)
- {
- Q3Object_Dispose(gDroneBulletColor);
- gDroneBulletColor = NULL;
- }
-
- if (gDroneNULLIllumination != NULL)
- {
- Q3Object_Dispose(gDroneNULLIllumination);
- gDroneNULLIllumination = NULL;
- }
-
- if (gDroneView != NULL)
- {
- Q3Object_Dispose(gDroneView);
- gDroneView = NULL;
- }
-
- if (gDroneDrawContext != NULL)
- {
- Q3Object_Dispose(gDroneDrawContext);
- gDroneDrawContext = NULL;
- }
-
- if (gDroneCamera != NULL)
- {
- Q3Object_Dispose(gDroneCamera);
- gDroneCamera = NULL;
- }
-
- if (gDronePick != NULL)
- {
- Q3Object_Dispose(gDronePick);
- gDronePick = NULL;
- }
-
- if (gDroneAutoMarkerEqual != NULL)
- {
- Q3Object_Dispose(gDroneAutoMarkerEqual);
- gDroneAutoMarkerEqual = NULL;
- }
-
- if (gDroneAutoMarkerAbove != NULL)
- {
- Q3Object_Dispose(gDroneAutoMarkerAbove);
- gDroneAutoMarkerAbove = NULL;
- }
-
- if (gDroneAutoMarkerBelow != NULL)
- {
- Q3Object_Dispose(gDroneAutoMarkerBelow);
- gDroneAutoMarkerBelow = NULL;
- }
- }
-
-
- /* =============================================================================
- * Drone_New (internal)
- *
- * Creates a new drone.
- * ========================================================================== */
- TDroneObject Drone_New(
- TDroneOrder inOrder)
- {
- TDroneObject drone;
- TDroneObject prev;
- TDroneObject next;
-
- // Allocate the memory
- drone = (TDroneObject) malloc(sizeof(TDroneData));
- assert(drone != NULL);
-
- drone->thumbprint = kThumbprint_Dead; // until finished with it
-
- // Find where to insert it
- prev = NULL;
- next = gDroneList;
- while (next != NULL && next->order < inOrder)
- {
- prev = next;
- next = next->next;
- }
-
- // Link it into the list
- drone->prev = prev;
- drone->next = next;
-
- if (prev != NULL)
- {
- prev->next = drone;
- }
- else
- {
- gDroneList = drone;
- }
-
- if (next != NULL)
- {
- next->prev = drone;
- }
-
- // Fill in the defaults
- drone->moveMethod = NULL;
- drone->updateSoundMethod = NULL;
- drone->submitMethod = NULL;
- drone->pickSubmitMethod = NULL;
- drone->hitMethod = NULL;
-
- drone->order = inOrder;
-
- drone->mark = false;
-
- drone->position.x = 0.0;
- drone->position.y = 0.0;
- drone->position.z = 0.0;
-
- drone->position1.x = 0.0;
- drone->position1.y = 0.0;
- drone->position1.z = 0.0;
-
- drone->velocity.x = 0.0;
- drone->velocity.y = 0.0;
- drone->velocity.z = 0.0;
-
- drone->velocity1.x = 0.0;
- drone->velocity1.y = 0.0;
- drone->velocity1.z = 0.0;
-
- drone->acceleration.x = 0.0;
- drone->acceleration.y = 0.0;
- drone->acceleration.z = 0.0;
-
- drone->direction.x = 1.0;
- drone->direction.y = 0.0;
- drone->direction.z = 0.0;
-
- drone->up.x = 0.0;
- drone->up.y = 1.0;
- drone->up.z = 0.0;
-
- drone->cross.x = 0.0;
- drone->cross.y = 0.0;
- drone->cross.z = 1.0;
-
- drone->geometry = NULL;
-
- drone->autoSndChannel = NULL;
- drone->autoSource = NULL;
- drone->autoSound = kAutoSound_None;
-
- drone->autoInterest = NULL;
-
- drone->autoVelocity.x = 0.0;
- drone->autoVelocity.y = 0.0;
- drone->autoVelocity.z = 0.0;
-
- drone->autoMode = kAutoMode_Idle;
- drone->autoModeTimeout = 0;
- drone->autoDistance = 0.0;
- drone->autoExplosion = 0.0;
-
- drone->bulletOrigin.x = 0.0;
- drone->bulletOrigin.y = 0.0;
- drone->bulletOrigin.z = 0.0;
-
- return drone;
- }
-
-
- /* =============================================================================
- * SelfDrone_New (external)
- *
- * Creates a new drone whose movement pattern is defined by user controls.
- * ========================================================================== */
- TDroneObject SelfDrone_New(
- void)
- {
- TDroneObject drone;
-
- // Create the basic drone
- drone = Drone_New(kDroneOrder_Self);
- assert(drone != NULL);
-
- // Fill in the fields
- drone->moveMethod = SelfDrone_Move;
-
- Q3Vector3D_Scale(&drone->direction, SELF_DRONE_INITIAL_SPEED, &drone->autoVelocity);
-
- // Validate it
- drone->thumbprint = kThumbprint_SelfDrone;
-
- return drone;
- }
-
-
- // **************************** GetSSpFilterVersion ****************************
- // Finds the manufacturer and version number of the SoundSprocket filter that
- // may be installed. inManufacturer should be the manufacturer code specified
- // at the installation time, which may be zero to allow any manufacturer.
- // If no error is encountered, outManufacturer is set to the actual manufacturer
- // code and outMajorVersion and outMinorVersion are set to the component
- // specification level and manufacturer's implementation revision, respectively.
- static OSStatus GetSSpFilterVersion(
- OSType inManufacturer,
- OSType* outManufacturer,
- UInt32* outMajorVersion,
- UInt32* outMinorVersion)
- {
- OSStatus err;
- ComponentDescription description;
- Component componentRef;
- UInt32 vers;
-
- // Set up the component description
- description.componentType = kSoundEffectsType;
- description.componentSubType = kSSpLocalizationSubType;
- description.componentManufacturer = inManufacturer;
- description.componentFlags = 0;
- description.componentFlagsMask = 0;
-
- // Find a component matching the description
- componentRef = FindNextComponent(nil, &description);
- if (componentRef == nil) return couldntGetRequiredComponent;
-
- // Get the component description (for the manufacturer code)
- err = GetComponentInfo(componentRef, &description, nil, nil, nil);
- if (err != noErr) return err;
-
- // Get the version composite
- vers = (UInt32) GetComponentVersion((ComponentInstance) componentRef);
-
- // Return the results
- *outManufacturer = description.componentManufacturer;
- *outMajorVersion = HiWord(vers);
- *outMinorVersion = LoWord(vers);
-
- return noErr;
- }
-
-
- /* =============================================================================
- * AutoDrone_New (external)
- *
- * Creates a new drone whose movement pattern is under automatic control.
- * ========================================================================== */
- TDroneObject AutoDrone_New(
- TDroneObject inDroneOfInterest)
- {
- OSStatus err;
- TDroneObject drone;
- TQ3Vector3D orientation;
- SoundComponentLink link;
- OSType manufacturer;
- UInt32 majorVersion;
- UInt32 minorVersion;
-
- assert(inDroneOfInterest != NULL && IS_DRONE(inDroneOfInterest));
-
- // Create the basic drone
- drone = Drone_New(kDroneOrder_Auto);
- assert(drone != NULL);
-
- // Fill in the fields
- drone->moveMethod = AutoDrone_Move;
- drone->updateSoundMethod = AutoDrone_UpdateSound;
- drone->submitMethod = AutoDrone_Submit;
- drone->pickSubmitMethod = AutoDrone_PickSubmit;
- drone->hitMethod = AutoDrone_Hit;
-
- // Allocate the sound channel and set up for 3D localized sound
- drone->autoSndChannel = NULL;
- SndNewChannel(&drone->autoSndChannel, sampledSynth, initMono, NULL);
- assert(drone->autoSndChannel != NULL);
-
- SSpSource_New(&drone->autoSource);
- assert(drone->autoSource != NULL);
-
- link.description.componentType = kSoundEffectsType;
- link.description.componentSubType = kSSpLocalizationSubType;
- link.description.componentManufacturer = 0;
- link.description.componentFlags = 0;
- link.description.componentFlagsMask = 0;
- link.mixerID = nil;
- link.linkID = nil;
-
- SndSetInfo(drone->autoSndChannel, siPreMixerSoundComponent, &link);
-
- // Verify that the right version filter was installed
- if (gDroneAutoCheckFilterVersion)
- {
- err = GetSSpFilterVersion(
- link.description.componentManufacturer,
- &manufacturer,
- &majorVersion,
- &minorVersion);
-
- if (err != noErr)
- {
- // Filter must not be installed
- // Note: A normal application would bail on 3D sound here
- StopAlert(kAlrtID_FilterNotInstalled, NULL);
- }
- else
- {
- // The major version represents the component specification level
- if (majorVersion < 1)
- {
- //• if we couldn't handle some old version, we could bail here.
-
- StopAlert(kAlrtID_FilterVersion, NULL);
- // Note: A normal application would bail on 3D sound here
- gSoundOn = false;
- }
- else
- {
- // The minor version specifies the manufacturer's implementation revision
-
- //• could do something here is we needed to handle tweaks for specific
- //• manufacturers or versions.
- }
- }
-
- gDroneAutoCheckFilterVersion = false;
- }
-
- if (gSoundOn)
- {
- // The sound is loudest out the back of the model
- Q3Vector3D_Set(&orientation, -1.0, 0.0, 0.0);
- SSpSource_SetOrientation(drone->autoSource, &orientation);
- }
-
- drone->autoInterest = inDroneOfInterest;
- drone->geometry = Q3Shared_GetReference(gDroneAutoGeometry);
-
- drone->position.x += Random()*0.0001 + AUTO_DRONE_LEAD;
- drone->position.y += Random()*0.0001;
- drone->position.z += Random()*0.0001;
-
- drone->autoVelocity.x += Random()*0.0001;
- drone->autoVelocity.y += Random()*0.0001;
- drone->autoVelocity.z += Random()*0.0001;
-
- // Validate it
- drone->thumbprint = kThumbprint_AutoDrone;
-
- return drone;
- }
-
-
- /* =============================================================================
- * BulletDrone_New (external)
- *
- * Creates a new drone whose behavior is projectile.
- * ========================================================================== */
- TDroneObject BulletDrone_New(
- const TQ3Point3D* inPosition,
- const TQ3Vector3D* inDirection)
- {
- TDroneObject drone;
-
- assert(inPosition != NULL);
- assert(inDirection != NULL);
-
- // Create the basic drone
- drone = Drone_New(kDroneOrder_Bullet);
- assert(drone != NULL);
-
- // Fill in the fields
- drone->moveMethod = BulletDrone_Move;
- drone->submitMethod = BulletDrone_Submit;
-
- drone->position = *inPosition;
- drone->direction = *inDirection;
-
- drone->bulletOrigin = *inPosition;
-
- // Validate it
- drone->thumbprint = kThumbprint_BulletDrone;
-
- return drone;
- }
-
-
- /* =============================================================================
- * Drone_Dispose (external)
- *
- * Disposes of the drone.
- * ========================================================================== */
- void Drone_Dispose(
- TDroneObject inDrone)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
-
- // Unlink it from the list
- if (inDrone->prev != NULL)
- {
- inDrone->prev->next = inDrone->next;
- }
- else
- {
- gDroneList = inDrone->next;
- }
-
- if (inDrone->next != NULL)
- {
- inDrone->next->prev = inDrone->prev;
- }
-
- // Dispose stuff
- if (inDrone->geometry != NULL)
- {
- Q3Object_Dispose(inDrone->geometry);
- inDrone->geometry = NULL;
- }
-
- // Free the sound channel
- //• This rightly belongs in AutoDrone_Dispose
- if (inDrone->autoSource != NULL)
- {
- SSpSource_Dispose(inDrone->autoSource);
- inDrone->autoSource = NULL;
- }
-
- if (inDrone->autoSndChannel != NULL)
- {
- SndDisposeChannel(inDrone->autoSndChannel, true);
- inDrone->autoSndChannel = NULL;
- }
-
- // Dispose of the memory
- inDrone->thumbprint = kThumbprint_Dead;
- free(inDrone);
- }
-
-
- /* =============================================================================
- * Drone_Next (external)
- *
- * If inDrone is NULL, then the head of the drone list is returned. If inDrone
- * is non-NULL, then the next drone in the list is returned. If inDrone is the
- * last drone, then NULL is returned.
- * ========================================================================== */
- TDroneObject Drone_Next(
- TDroneObject inDrone)
- {
- TDroneObject result;
-
- if (inDrone != NULL)
- {
- assert(IS_DRONE(inDrone));
-
- result = inDrone->next;
- }
- else
- {
- result = gDroneList;
- }
-
- return result;
- }
-
-
- /* =============================================================================
- * Drone_Move (external)
- *
- * Moves the drone forward one time step. This may mark the drone for death.
- * ========================================================================== */
- void Drone_Move(
- TDroneObject inDrone)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
-
- // Move the drone by its own rules
- assert(inDrone->moveMethod != NULL);
- (inDrone->moveMethod)(inDrone);
-
- // Drone is still alive -- compute the velocity and acceleration
- Q3Point3D_Subtract(&inDrone->position, &inDrone->position1, &inDrone->velocity);
- Q3Vector3D_Scale(&inDrone->velocity, gGameFramesPerSecond, &inDrone->velocity);
- inDrone->position1 = inDrone->position;
-
- Q3Vector3D_Subtract(&inDrone->velocity, &inDrone->velocity1, &inDrone->acceleration);
- Q3Vector3D_Scale(&inDrone->acceleration, gGameFramesPerSecond, &inDrone->acceleration);
- inDrone->velocity1 = inDrone->velocity;
-
- // Reorthogonalize the up and cross vectors
- assert(fabs(Q3Vector3D_Length(&inDrone->direction) - 1.0) < 0.05);
-
- Q3Vector3D_Cross(&inDrone->direction, &inDrone->up, &inDrone->cross);
- Q3Vector3D_Normalize(&inDrone->cross, &inDrone->cross);
-
- Q3Vector3D_Cross(&inDrone->cross, &inDrone->direction, &inDrone->up);
- }
-
-
-
- /* =============================================================================
- * AutoDrone_Move (internal)
- *
- * Moves the drone forward one time step. The autopilot drone has a constant
- * thrust along its direction of orientation. The direction is controlled to
- * point just in front of the drone of interest.
- * ========================================================================== */
- void AutoDrone_Move(
- TDroneObject inDrone)
- {
- TQ3Vector3D newDirection;
- TQ3Vector3D v1;
- TQ3Vector3D v2;
- TQ3Point3D target;
- float distance;
- float turnRate;
- float limit;
- TAutoSound newSound;
- SndCommand sndCommand;
- long base;
- TQ3Matrix4x4 matrix;
-
- assert(inDrone != NULL && IS_AUTO_DRONE(inDrone));
-
- // Figure out new direction
- if (inDrone->autoMode == kAutoMode_Explosion)
- {
- // Point the explosion geometry at the camera
- //• NOTE: For now, we assume that the camera is at the drone of interest
- //• This is wrong for two reasons. First, the camera could actually be
- //• elsewhere. Second, this assumes that the drone of interest moves
- //• before this drone.
- Q3Point3D_Subtract(
- &inDrone->autoInterest->position,
- &inDrone->position,
- &newDirection);
-
- Q3Vector3D_Normalize(&newDirection, &inDrone->direction);
- }
- else
- {
- // Find a point in front of the drone of interest
- assert(IS_DRONE(inDrone->autoInterest));
-
- Q3Vector3D_Scale(&inDrone->autoInterest->direction, AUTO_DRONE_LEAD, &v1);
- Q3Point3D_Vector3D_Add(&inDrone->autoInterest->position, &v1, &target);
-
- // Point toward the target
- Q3Point3D_Subtract(&target, &inDrone->position, &newDirection);
- Q3Vector3D_Normalize(&newDirection, &newDirection);
-
- // Limit the turn rate
- turnRate = acosf(Q3Vector3D_Dot(&inDrone->direction, &newDirection));
- limit = AUTO_DRONE_TURN_RATE*gGameInterval;
- if (turnRate > limit)
- {
- // Limit the turn
- // Note: this should actually be spherical interpolation -- but linear is close enough
- turnRate = limit/turnRate;
- Q3Vector3D_Scale(&inDrone->direction, 1.0-turnRate, &v1);
- Q3Vector3D_Scale(&newDirection, turnRate, &v2);
- Q3Vector3D_Add(&v1, &v2, &inDrone->direction);
- Q3Vector3D_Normalize(&inDrone->direction, &inDrone->direction);
- }
- else
- {
- // It's OK to make the desired turn
- inDrone->direction = newDirection;
- }
- }
-
- // Figure out new position
- switch (inDrone->autoMode)
- {
- case kAutoMode_Idle: // Start a burn if we are getting farther from the target
- // Start burn if we are getting farther from the target
- distance = Q3Point3D_Distance(&inDrone->position, &target);
- if (inDrone->autoDistance > distance)
- {
- // Getting closer to target -- don't change
- inDrone->autoDistance = distance;
- }
- else
- {
- // Getting farther from target -- start a burn
- inDrone->autoMode = kAutoMode_Burn;
- inDrone->autoModeTimeout = TickCount() + (unsigned long) (AUTO_DRONE_BURN_TIME*60);
- }
- break;
-
- case kAutoMode_Burn: // Accelerate toward the target
- // Continue the burn?
- if (TickCount() <= inDrone->autoModeTimeout)
- {
- // Still burning -- change the velocity by accelerating toward the target
- Q3Vector3D_Scale(&inDrone->direction, gGameInterval*AUTO_DRONE_ACCEL, &v1);
- Q3Vector3D_Add(&inDrone->autoVelocity, &v1, &inDrone->autoVelocity);
- }
- else
- {
- // Switch to rest mode
- inDrone->autoMode = kAutoMode_Rest;
- inDrone->autoModeTimeout = TickCount() + (unsigned long) (AUTO_DRONE_REST_TIME*60);
- }
- break;
-
- case kAutoMode_Rest: // Don't use the engine for a while
- // Continue the rest?
- if (TickCount() <= inDrone->autoModeTimeout)
- {
- // Still resting
- // (do nothing)
- }
- else
- {
- // Switch to idle mode
- inDrone->autoMode = kAutoMode_Idle;
- inDrone->autoDistance = Q3Point3D_Distance(&inDrone->position, &target);
- }
- break;
-
- case kAutoMode_Explosion: // Show the explosion for a while
- // Continue the explosion?
- inDrone->autoExplosion += gGameInterval/AUTO_DRONE_EXPLOSION_TIME;
- if (inDrone->autoExplosion <= 1.0)
- {
- // Still exploding
- inDrone->autoVelocity.x =
- inDrone->autoVelocity.y =
- inDrone->autoVelocity.z = 0.0;
- }
- else
- {
- // Kill the drone
- Drone_SetMark(inDrone, true);
- }
- break;
-
- default:
- assert(0);
- }
-
- // Move along the new velocity vector
- Q3Vector3D_Scale(&inDrone->autoVelocity, gGameInterval, &v1);
- Q3Point3D_Vector3D_Add(&inDrone->position, &v1, &inDrone->position);
-
- if (gSoundOn)
- {
- // Choose the next sound to play
- switch (inDrone->autoMode)
- {
- case kAutoMode_Idle:
- case kAutoMode_Rest:
- newSound = kAutoSound_Idle;
- break;
-
- case kAutoMode_Burn:
- newSound = kAutoSound_Burn;
- break;
-
- break;
-
- case kAutoMode_Explosion:
- newSound = kAutoSound_Explosion;
- break;
-
- default:
- assert(0);
- }
-
- // Change the sound
- if (inDrone->autoSound != newSound)
- {
- // Stop the old sound
- if (inDrone->autoSound != kAutoSound_None)
- {
- sndCommand.cmd = quietCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = 0;
- SndDoImmediate(inDrone->autoSndChannel, &sndCommand);
- }
-
- inDrone->autoSound = newSound;
-
- // Play the new sound
- switch (inDrone->autoSound)
- {
- case kAutoSound_None:
- base = 0;
- break;
-
- case kAutoSound_Idle:
- base = (long) *gDroneAutoSndIdle + gDroneAutoSndIdleOffset;
- SSpSource_SetAngularAttenuation(inDrone->autoSource, 0.0, 0.0);
- SSpSource_SetReferenceDistance(inDrone->autoSource, AUTO_DRONE_IDLE_REF_DIST);
- break;
-
- case kAutoSound_Burn:
- base = (long) *gDroneAutoSndBurn + gDroneAutoSndBurnOffset;
- SSpSource_SetAngularAttenuation(inDrone->autoSource, 1.5, -12.0);
- SSpSource_SetReferenceDistance(inDrone->autoSource, AUTO_DRONE_BURN_REF_DIST);
- break;
-
- case kAutoSound_Explosion:
- base = (long) *gDroneAutoSndExplosion + gDroneAutoSndExplosionOffset;
- SSpSource_SetAngularAttenuation(inDrone->autoSource, 0.0, 0.0);
- SSpSource_SetReferenceDistance(inDrone->autoSource, AUTO_DRONE_EXPL_REF_DIST);
- break;
-
- default:
- assert(0);
- }
-
- if (base != 0)
- {
- // Install the sound
- sndCommand.cmd = soundCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = base;
- SndDoImmediate(inDrone->autoSndChannel, &sndCommand);
-
- // Play it indefinitely
- sndCommand.cmd = freqCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = 60;
- SndDoImmediate(inDrone->autoSndChannel, &sndCommand);
- }
- }
-
- // Change the sound source location
- Drone_GetMatrix(inDrone, &matrix);
- SSpSource_SetTransform(inDrone->autoSource, &matrix);
- }
- }
-
-
- /* =============================================================================
- * BulletDrone_Move (internal)
- *
- * Moves the drone forward one time step.
- * ========================================================================== */
- void BulletDrone_Move(
- TDroneObject inDrone)
- {
- TQ3Vector3D v;
- float prevDistance;
- float currDistance;
- TQ3CameraPlacement placement;
- TDroneObject target;
- unsigned long count;
- unsigned long index;
-
- assert(inDrone != NULL && IS_BULLET_DRONE(inDrone));
-
- // Move the bullet
- prevDistance = Q3Point3D_Distance(&inDrone->position, &inDrone->bulletOrigin);
-
- Q3Vector3D_Scale(&inDrone->direction, gGameInterval*BULLET_DRONE_SPEED, &v);
- Q3Point3D_Vector3D_Add(&inDrone->position, &v, &inDrone->position);
-
- currDistance = Q3Point3D_Distance(&inDrone->position, &inDrone->bulletOrigin);
-
- // Time to expire?
- if (currDistance > BULLET_DRONE_LIMIT)
- {
- // Mark the drone to die
- Drone_SetMark(inDrone, true);
- }
- else
- {
- // Set up for collision detection
- placement.cameraLocation = inDrone->bulletOrigin;
- placement.upVector = inDrone->up;
-
- Q3Point3D_Vector3D_Add(&inDrone->bulletOrigin, &inDrone->direction, &placement.pointOfInterest);
-
- Q3Camera_SetPlacement(gDroneCamera, &placement);
-
- // Collision detection with all target drones
- Q3View_StartPicking(gDroneView, gDronePick);
- do
- {
- for (target = Drone_Next(NULL); target != NULL; target = Drone_Next(target))
- {
- // Submit the drone geometry, along with a PickID that is the object reference
- Q3PickIDStyle_Submit((unsigned long) target, gDroneView);
- Drone_PickSubmit(target, gDroneView);
- }
- }
- while (Q3View_EndPicking(gDroneView) == kQ3ViewStatusRetraverse);
-
- // Check the hit list
- Q3Pick_GetNumHits(gDronePick, &count);
- for (index = 0; index < count; index++)
- {
- UInt32 pickGood, maskGood;
-
- Q3Pick_GetPickDetailData(gDronePick, index, kQ3PickDetailMaskPickID, &pickGood);
- Q3Pick_GetPickDetailData(gDronePick, index, kQ3PickDetailMaskDistance, &maskGood);
-
- if (pickGood && maskGood)
- {
- Q3Pick_GetPickDetailData(gDronePick, index, kQ3PickDetailMaskPickID, &target);
-
- if (target != NULL && IS_DRONE(target))
- {
- // Got a valid hit -- check its range
- //• Should it be a bullet or a laser?
- // if ((1 || prevDistance <= hitData.distance) && hitData.distance <= currDistance)
- if (true)
- {
- // Hit it!
- Drone_Hit(target);
-
- // Kill the bullet
- Drone_SetMark(inDrone, true);
- break;
- }
- }
- }
-
- // Q3Hit_EmptyData(&hitData);
- }
-
- // Empty out the pick hits
- Q3Pick_EmptyHitList(gDronePick);
- }
- }
-
-
- /* =============================================================================
- * Drone_UpdateSound (external)
- *
- * Updates localized sounds for this drone. The default method does nothing.
- * ========================================================================== */
- void Drone_UpdateSound(
- TDroneObject inDrone)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
-
- if (inDrone->updateSoundMethod != NULL)
- {
- (inDrone->updateSoundMethod)(inDrone);
- }
- }
-
-
- /* =============================================================================
- * AutoDrone_UpdateSound (external)
- *
- * Updates localized sounds for this autopilot drone.
- * ========================================================================== */
- void AutoDrone_UpdateSound(
- TDroneObject inDrone)
- {
- SSpLocalizationData snd3DInfo;
-
- assert(inDrone != NULL && IS_AUTO_DRONE(inDrone));
-
- if (gSoundOn)
- {
- SSpSource_CalcLocalization(inDrone->autoSource, Sound_GetListener(), &snd3DInfo);
-
- SndSetInfo(inDrone->autoSndChannel, siSSpLocalization, &snd3DInfo);
- }
- }
-
-
- /* =============================================================================
- * Drone_Submit (external)
- *
- * Submits the drone for drawing.
- * ========================================================================== */
- void Drone_Submit(
- TDroneObject inDrone,
- Boolean inHUDVisible,
- TQ3ViewObject inView)
- {
- TQ3Matrix4x4 matrix;
-
- assert(inDrone != NULL && IS_DRONE(inDrone));
-
- if (inDrone->submitMethod != NULL)
- {
- // Use the submit method
- (inDrone->submitMethod)(inDrone, inHUDVisible, inView);
- }
- else if (inDrone->geometry != NULL)
- {
- // Submit the geometry
- Drone_GetMatrix(inDrone, &matrix);
-
- Q3Push_Submit(inView);
- Q3MatrixTransform_Submit(&matrix, inView);
- Q3Object_Submit(inDrone->geometry, inView);
- Q3Pop_Submit(inView);
- }
- }
-
-
- /* =============================================================================
- * AutoDrone_Submit (internal)
- *
- * Submits the bullet drone for drawing.
- * ========================================================================== */
- void AutoDrone_Submit(
- TDroneObject inDrone,
- Boolean inHUDVisible,
- TQ3ViewObject inView)
- {
- TQ3Matrix4x4 matrix;
- TQ3ColorRGB transparency;
- TQ3Point3D position;
- TQ3Vector3D direction;
- TQ3Vector3D up;
- TQ3Vector3D right;
- TQ3Vector3D v;
- TQ3Vector3D v1;
- TQ3Vector3D v2;
- float height;
- TQ3GeometryObject marker;
-
- assert(inDrone != NULL && IS_AUTO_DRONE(inDrone));
- assert(inView != NULL);
-
- // Draw the drone
- Q3Push_Submit(inView);
-
- Drone_GetMatrix(inDrone, &matrix);
- Q3MatrixTransform_Submit(&matrix, inView);
-
- switch (inDrone->autoMode)
- {
- case kAutoMode_Burn:
- Q3Object_Submit(gDroneAutoBurnGeometry, inView);
- /* FALL THROUGH TO SUBMIT DRONE GEOMETRY */
-
- case kAutoMode_Rest:
- case kAutoMode_Idle:
- Q3Object_Submit(inDrone->geometry, inView);
- break;
-
- case kAutoMode_Explosion:
- // Grow the explosion
- v.x = v.y = v.z = (1.0-AUTO_DRONE_MIN_SCALE)*inDrone->autoExplosion + AUTO_DRONE_MIN_SCALE;
- Q3ScaleTransform_Submit(&v, inView);
-
- // Fade at the end
- if (inDrone->autoExplosion > (1.0-AUTO_DRONE_FADE_TIME))
- {
- transparency.r =
- transparency.g =
- transparency.b = (-1.0/AUTO_DRONE_FADE_TIME)*inDrone->autoExplosion + (1.0/AUTO_DRONE_FADE_TIME);
-
- Q3Attribute_Submit(kQ3AttributeTypeTransparencyColor, &transparency, inView);
- }
-
- // Submit the explosion geometry
- Q3Object_Submit(gDroneAutoExplosionGeometry, inView);
- break;
-
- default:
- assert(0);
- }
-
- Q3Pop_Submit(inView);
-
- // Draw the HUD marker for the drone
- if (inHUDVisible && inDrone->autoMode != kAutoMode_Explosion)
- {
- Display_GetViewerPosition(&position, &direction, &up);
- Q3Vector3D_Cross(&direction, &up, &right);
-
- Q3Point3D_Subtract(&inDrone->position, &position, &v);
-
- Q3Vector3D_Scale(&up, HUD_SCALE*Q3Vector3D_Dot(&direction, &v), &v1);
- Q3Vector3D_Scale(&right, HUD_SCALE*Q3Vector3D_Dot(&right, &v), &v2);
-
- Q3Point3D_Vector3D_Add(&position, &direction, &position);
- Q3Point3D_Vector3D_Add(&position, &v1, &position);
- Q3Point3D_Vector3D_Add(&position, &v2, &position);
-
- Q3Vector3D_Normalize(&v, &v);
- height = Q3Vector3D_Dot(&up, &v);
- if (height >= HUD_HEIGHT)
- {
- marker = gDroneAutoMarkerAbove;
- }
- else if (height <= -HUD_HEIGHT)
- {
- marker = gDroneAutoMarkerBelow;
- }
- else
- {
- marker = gDroneAutoMarkerEqual;
- }
-
- Q3Marker_SetPosition(marker, &position);
- Q3Object_Submit(marker, inView);
- }
- }
-
-
- /* =============================================================================
- * BulletDrone_Submit (internal)
- *
- * Submits the bullet drone for drawing.
- * ========================================================================== */
- void BulletDrone_Submit(
- TDroneObject inDrone,
- Boolean inHUDVisible,
- TQ3ViewObject inView)
- {
- TQ3LineData lineData;
-
- assert(inDrone != NULL && IS_BULLET_DRONE(inDrone));
- assert(inView != NULL);
-
- lineData.vertices[0].point = inDrone->bulletOrigin;
- lineData.vertices[0].attributeSet = NULL;
- lineData.vertices[1].point = inDrone->position;
- lineData.vertices[1].attributeSet = NULL;
- lineData.lineAttributeSet = NULL;
-
- Q3Push_Submit(inView);
- Q3Object_Submit(gDroneNULLIllumination, inView);
- Q3Object_Submit(gDroneBulletColor, inView);
- Q3Line_Submit(&lineData, inView);
- Q3Pop_Submit(inView);
- }
-
-
- /* =============================================================================
- * Drone_PickSubmit (internal)
- *
- * Submits the drone for picking against a bullet. It forwards to the actual
- * drone hit method, if any.
- * ========================================================================== */
- void Drone_PickSubmit(
- TDroneObject inDrone,
- TQ3ViewObject inView)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
-
- if (inDrone->pickSubmitMethod != NULL)
- {
- (*inDrone->pickSubmitMethod)(inDrone, inView);
- }
- }
-
-
- /* =============================================================================
- * AutoDrone_PickSubmit (internal)
- *
- * Submits the autopilot drone for picking against a bullet.
- * ========================================================================== */
- void AutoDrone_PickSubmit(
- TDroneObject inDrone,
- TQ3ViewObject inView)
- {
- TQ3Matrix4x4 matrix;
-
- assert(inDrone != NULL && IS_AUTO_DRONE(inDrone));
- assert(inView != NULL);
-
- // Draw the drone
- if (inDrone->autoMode != kAutoMode_Explosion)
- {
- Q3Push_Submit(inView);
-
- Drone_GetMatrix(inDrone, &matrix);
- Q3MatrixTransform_Submit(&matrix, inView);
-
- Q3Object_Submit(gDroneAutoBurnGeometry, inView);
-
- Q3Pop_Submit(inView);
- }
- }
-
-
- /* =============================================================================
- * Drone_Hit (internal)
- *
- * Called when this drone is hit. It forwards to the actual drone hit method,
- * if any.
- * ========================================================================== */
- void Drone_Hit(
- TDroneObject inDrone)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
-
- if (inDrone->hitMethod != NULL)
- {
- (*inDrone->hitMethod)(inDrone);
- }
- }
-
-
- /* =============================================================================
- * AutoDrone_Hit (internal)
- *
- * Called when this autopilot drone is hit. It puts the drone into
- * explosion mode.
- * ========================================================================== */
- void AutoDrone_Hit(
- TDroneObject inDrone)
- {
- assert(inDrone != NULL && IS_AUTO_DRONE(inDrone));
-
- inDrone->autoMode = kAutoMode_Explosion;
- inDrone->autoExplosion = 0.0;
- }
-
-
- /* =============================================================================
- * Drone_SetMark (external)
- *
- * Changes the drone's mark to the given value. The mark is used to indicate
- * which drones should die.
- * ========================================================================== */
- void Drone_SetMark(
- TDroneObject inDrone,
- Boolean inMark)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
-
- inDrone->mark = inMark;
- }
-
-
- /* =============================================================================
- * Drone_GetMark (external)
- *
- * Returns the drone's mark.
- * ========================================================================== */
- Boolean Drone_GetMark(
- TDroneObject inDrone)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
-
- return inDrone->mark;
- }
-
-
- /* =============================================================================
- * Drone_GetPosition (external)
- *
- * Returns the current position in outPosition.
- * ========================================================================== */
- void Drone_GetPosition(
- TDroneObject inDrone,
- TQ3Point3D* outPosition)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
- assert(outPosition != NULL);
-
- *outPosition = inDrone->position;
- }
-
-
- /* =============================================================================
- * Drone_GetVelocity (external)
- *
- * Returns the current velocity in outVelocity
- * ========================================================================== */
- void Drone_GetVelocity(
- TDroneObject inDrone,
- TQ3Vector3D* outVelocity)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
- assert(outVelocity != NULL);
-
- *outVelocity = inDrone->velocity;
- }
-
-
- /* =============================================================================
- * Drone_GetDirection (external)
- *
- * Returns the current direction in outDirection.
- * ========================================================================== */
- void Drone_GetDirection(
- TDroneObject inDrone,
- TQ3Vector3D* outDirection)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
- assert(outDirection != NULL);
-
- *outDirection = inDrone->direction;
- }
-
-
- /* =============================================================================
- * Drone_GetUp (external)
- *
- * Returns the current up vector in outUp.
- * ========================================================================== */
- void Drone_GetUp(
- TDroneObject inDrone,
- TQ3Vector3D* outUp)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
- assert(outUp != NULL);
-
- *outUp = inDrone->up;
- }
-
-
- /* =============================================================================
- * Drone_GetMatrix (external)
- *
- * Returns the matrix that transforms to the drone position and orientation.
- * ========================================================================== */
- void Drone_GetMatrix(
- TDroneObject inDrone,
- TQ3Matrix4x4* outMatrix)
- {
- assert(inDrone != NULL && IS_DRONE(inDrone));
- assert(outMatrix != NULL);
-
- outMatrix->value[0][0] = inDrone->direction.x;
- outMatrix->value[0][1] = inDrone->direction.y;
- outMatrix->value[0][2] = inDrone->direction.z;
-
- outMatrix->value[1][0] = inDrone->up.x;
- outMatrix->value[1][1] = inDrone->up.y;
- outMatrix->value[1][2] = inDrone->up.z;
-
- outMatrix->value[2][0] = inDrone->cross.x;
- outMatrix->value[2][1] = inDrone->cross.y;
- outMatrix->value[2][2] = inDrone->cross.z;
-
- outMatrix->value[3][0] = inDrone->position.x;
- outMatrix->value[3][1] = inDrone->position.y;
- outMatrix->value[3][2] = inDrone->position.z;
-
- outMatrix->value[0][3] = 0.0;
- outMatrix->value[1][3] = 0.0;
- outMatrix->value[2][3] = 0.0;
- outMatrix->value[3][3] = 1.0;
- }
-
-
- /* =============================================================================
- * Drone_Fire (external)
- *
- * Called each time the fire button is pressed.
- * ========================================================================== */
- void Drone_Fire(
- TDroneObject inDrone)
- {
- TQ3Vector3D up;
- TQ3Vector3D cross;
- TQ3Point3D origin;
-
- assert(inDrone != NULL && IS_DRONE(inDrone));
-
- // Find the offsets
- Q3Vector3D_Scale(&inDrone->up, BULLET_DRONE_OFFSET, &up);
- Q3Vector3D_Scale(&inDrone->cross, BULLET_DRONE_OFFSET, &cross);
-
- // Fire one
- Q3Point3D_Vector3D_Subtract(&inDrone->position, &up, &origin);
- Q3Point3D_Vector3D_Subtract(&origin, &cross, &origin);
- BulletDrone_New(&origin, &inDrone->direction);
-
- // Fire two
- Q3Point3D_Vector3D_Subtract(&inDrone->position, &up, &origin);
- Q3Point3D_Vector3D_Add(&origin, &cross, &origin);
- BulletDrone_New(&origin, &inDrone->direction);
- }
-
-
- /* =============================================================================
- * Drone_Silence (external)
- *
- * Silences any drone sounds.
- * ========================================================================== */
- void Drone_Silence(
- TDroneObject inDrone)
- {
- SndCommand sndCommand;
-
- assert(inDrone != NULL && IS_DRONE(inDrone));
-
- //• We should really do this as AutoDrone_Silence, but whatever...
-
- if (inDrone->autoSndChannel != NULL)
- {
- // Purge any pending commands
- sndCommand.cmd = flushCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = 0;
- SndDoImmediate(inDrone->autoSndChannel, &sndCommand);
-
- // Quiet the current sound
- sndCommand.cmd = quietCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = 0;
- SndDoImmediate(inDrone->autoSndChannel, &sndCommand);
- }
- }
-
- /* =============================================================================
- * SelfDrone_Move (internal)
- *
- * Moves the drone forward one time step.
- * ========================================================================== */
- void SelfDrone_Move(
- TDroneObject inDrone)
- {
- TQ3Vector3D v;
-
- assert(inDrone != NULL && IS_SELF_DRONE(inDrone));
-
- // Move along the velocity vector
- Q3Vector3D_Scale(&inDrone->autoVelocity, gGameInterval, &v);
- Q3Point3D_Vector3D_Add(&inDrone->position, &v, &inDrone->position);
-
- #if SELF_DRONE_HAS_FRICTION
- // automatically slow ship down if no thrust (like friction)
- Q3Vector3D_Scale(&inDrone->autoVelocity, SELF_DRONE_FRICTION, &inDrone->autoVelocity);
- #endif
- }
-
- /* =============================================================================
- * SelfDrone_Thrust (external)
- *
- * Increases the velocity of the drone.
- * ========================================================================== */
- void SelfDrone_Thrust(
- TDroneObject inDrone,
- float inThrust)
- {
- TQ3Vector3D v;
-
- assert(inDrone != NULL && IS_SELF_DRONE(inDrone));
-
- // change the velocity by accelerating inThrust amount
- Q3Vector3D_Scale(&inDrone->direction, inThrust*SELF_DRONE_MAX_ACCEL, &v);
- Q3Vector3D_Add(&inDrone->autoVelocity, &v, &inDrone->autoVelocity);
- }
-
- /* =============================================================================
- * SelfDrone_DampVelocity (external)
- *
- * Increases the velocity of the drone.
- * ========================================================================== */
- void SelfDrone_DampVelocity(
- TDroneObject inDrone,
- float inDampingPercentage)
- {
- assert(inDrone != NULL && IS_SELF_DRONE(inDrone));
-
- // automatically slow ship down if no thrust (like friction)
- Q3Vector3D_Scale(&inDrone->autoVelocity, inDampingPercentage, &inDrone->autoVelocity);
- }
-
- /* =============================================================================
- * SelfDrone_AllStop (external)
- *
- * Increases the velocity of the drone.
- * ========================================================================== */
- void SelfDrone_InstantStop(
- TDroneObject inDrone)
- {
- assert(inDrone != NULL && IS_SELF_DRONE(inDrone));
-
- // automatically slow ship down if no thrust (like friction)
- Q3Vector3D_Scale(&inDrone->autoVelocity, 0.0, &inDrone->autoVelocity);
- }
-
-
-
- /* =============================================================================
- * SelfDrone_Pitch (external)
- *
- * Changes the direction of the ship by the given angles, in radians.
- * ========================================================================== */
- void SelfDrone_Pitch(
- TDroneObject inDrone,
- float inPitchAngle)
- {
- TQ3Vector3D v1;
- TQ3Vector3D v2;
-
- assert(inDrone != NULL && IS_SELF_DRONE(inDrone));
-
- if (inPitchAngle != 0.0)
- {
- Q3Vector3D_Scale(&inDrone->direction, cosf(inPitchAngle), &v1);
- Q3Vector3D_Scale(&inDrone->up, sinf(inPitchAngle), &v2);
- Q3Vector3D_Add(&v1, &v2, &inDrone->direction);
- }
- }
-
-
- /* =============================================================================
- * SelfDrone_Yaw (external)
- *
- * Changes the direction of the ship by the given angles, in radians.
- * ========================================================================== */
- void SelfDrone_Yaw(
- TDroneObject inDrone,
- float inYawAngle)
- {
- TQ3Vector3D v1;
- TQ3Vector3D v2;
-
- assert(inDrone != NULL && IS_SELF_DRONE(inDrone));
-
- if (inYawAngle != 0.0)
- {
- Q3Vector3D_Scale(&inDrone->direction, cosf(inYawAngle), &v1);
- Q3Vector3D_Scale(&inDrone->cross, sinf(inYawAngle), &v2);
- Q3Vector3D_Add(&v1, &v2, &inDrone->direction);
- }
- }
-
-
- /* =============================================================================
- * SelfDrone_Roll (external)
- *
- * Changes the direction of the ship by the given angles, in radians.
- * ========================================================================== */
- void SelfDrone_Roll(
- TDroneObject inDrone,
- float inRollAngle)
- {
- TQ3Vector3D v1;
- TQ3Vector3D v2;
-
- assert(inDrone != NULL && IS_SELF_DRONE(inDrone));
-
- if (inRollAngle != 0.0)
- {
- Q3Vector3D_Scale(&inDrone->up, cosf(inRollAngle), &v1);
- Q3Vector3D_Scale(&inDrone->cross, sinf(inRollAngle), &v2);
- Q3Vector3D_Add(&v1, &v2, &inDrone->up);
- }
- }
-
- /*
- {
- matrix = BuildRotationMatrix (angle, x, y, z)
-
- up = Multiply (up, matrix);
-
- normalize?
- }
- */